C.S.Burner 🪙 ━►🔥GIT Node
Node / reticulum_mirror / MeshChatX / files / meshchatx / src / frontend / components / MdiIconPickerModal.vue
Displaying Raw • Download
meshchatx/src/frontend/components/MdiIconPickerModal.vue 65ca9ddc823fcc2c8f8653c553b944b85db0875f (65ca9ddc) Text, 5.49 KB
T8b949e<!-- SPDX-License-Identifier: 0BSD AND MIT -->
Tff7b72<templateTff7b72>
Tff7b72<div
Te6edf3v-if=Ta5d6ff"open"
Te6edf3class=Ta5d6ff"fixed inset-0 z-[60] flex items-center justify-center bg-black/50 p-4"
@Te6edf3click.self=Ta5d6ff"$emit('close')"
Tff7b72>
Tff7b72<div
Te6edf3class=Ta5d6ff"flex w-full max-w-lg max-h-[min(36rem,90vh)] flex-col rounded-2xl border border-sem-border-card bg-sem-surface shadow-xl"
Te6edf3role=Ta5d6ff"dialog"
Te6edf3:aria-label=Ta5d6ff"$t('relay_chat.hub_icon_picker_title')"
Tff7b72>
Tff7b72<div Te6edf3class=Ta5d6ff"flex items-center justify-between gap-2 border-b border-sem-border px-5 py-4"Tff7b72>
Tff7b72<h2 Te6edf3class=Ta5d6ff"text-lg font-semibold"Tff7b72>Tff7b72{{ $Te6edf3tTff7b72(Ta5d6ff"relay_chat.hub_icon_picker_title"Tff7b72) Tff7b72}}Tff7b72</h2>
Tff7b72<button
Te6edf3type=Ta5d6ff"button"
Te6edf3class=Ta5d6ff"rounded-lg p-1 text-sem-fg-muted hover:bg-sem-surface/60"
Te6edf3:title=Ta5d6ff"$t('common.close')"
@Te6edf3click=Ta5d6ff"$emit('close')"
Tff7b72>
Tff7b72<MaterialDesignIcon Te6edf3icon-name=Ta5d6ff"close" Te6edf3class=Ta5d6ff"size-5" Tff7b72/>
Tff7b72</button>
Tff7b72</div>
Tff7b72<div Te6edf3class=Ta5d6ff"px-5 pt-3"Tff7b72>
Tff7b72<div Te6edf3class=Ta5d6ff"relative"Tff7b72>
Tff7b72<input
Te6edf3ref=Ta5d6ff"searchInput"
Te6edf3v-model=Ta5d6ff"search"
Te6edf3type=Ta5d6ff"text"
Te6edf3:placeholder=Ta5d6ff"$t('relay_chat.hub_icon_search', { count: iconNames.length })"
Te6edf3class=Ta5d6ff"input-field !py-2.5 pr-10"
Tff7b72/>
Tff7b72<MaterialDesignIcon
Te6edf3icon-name=Ta5d6ff"magnify"
Te6edf3class=Ta5d6ff"pointer-events-none absolute right-3 top-1/2 size-5 -translate-y-1/2 text-sem-fg-muted"
Tff7b72/>
Tff7b72</div>
Tff7b72</div>
Tff7b72<div Te6edf3class=Ta5d6ff"flex-1 overflow-y-auto custom-scrollbar px-5 py-3"Tff7b72>
Tff7b72<div Te6edf3class=Ta5d6ff"grid grid-cols-4 sm:grid-cols-5 gap-2"Tff7b72>
Tff7b72<button
Te6edf3v-for=Ta5d6ff"iconName in searchedIconNames"
Te6edf3:key=Ta5d6ff"iconName"
Te6edf3type=Ta5d6ff"button"
Te6edf3class=Ta5d6ff"flex flex-col items-center gap-1 rounded-lg border p-2 transition-colors hover:bg-sem-surface/60"
Te6edf3:class=Ta5d6ff"selectedIcon === iconName ? 'border-sem-accent bg-sem-accent/10' : 'border-sem-border'"
Te6edf3:title=Ta5d6ff"iconName"
@Te6edf3click=Ta5d6ff"pick(iconName)"
Tff7b72>
Tff7b72<MaterialDesignIcon Te6edf3:icon-name=Ta5d6ff"iconName" Te6edf3class=Ta5d6ff"size-7" Te6edf3:class=Ta5d6ff"previewIconClass" Tff7b72/>
Tff7b72<span Te6edf3class=Ta5d6ff"w-full truncate text-center text-[10px] text-sem-fg-muted"Tff7b72>Tff7b72{{ Te6edf3iconName Tff7b72}}Tff7b72</span>
Tff7b72</button>
Tff7b72</div>
Tff7b72<div Te6edf3v-if=Ta5d6ff"searchedIconNames.length === 0" Te6edf3class=Ta5d6ff"py-8 text-center text-sm text-sem-fg-muted"Tff7b72>
Tff7b72{{ $Te6edf3tTff7b72(Ta5d6ff"relay_chat.hub_icon_no_results"Tff7b72) Tff7b72}}
Tff7b72</div>
Tff7b72<div
Te6edf3v-else-if=Ta5d6ff"searchedIconNames.length >= maxSearchResults"
Te6edf3class=Ta5d6ff"pt-2 text-center text-xs text-sem-fg-muted"
Tff7b72>
Tff7b72{{ $Te6edf3tTff7b72(Ta5d6ff"relay_chat.hub_icon_search_limit"Tff7b72, Tff7b72{ Te6edf3countTff7b72: Te6edf3maxSearchResults Tff7b72}Tff7b72) Tff7b72}}
Tff7b72</div>
Tff7b72</div>
Tff7b72<div Te6edf3class=Ta5d6ff"flex justify-between gap-2 border-t border-sem-border px-5 py-3"Tff7b72>
Tff7b72<button Te6edf3type=Ta5d6ff"button" Te6edf3:class=Ta5d6ff"btnSecondary" @Te6edf3click=Ta5d6ff"pick(null)"Tff7b72>
Tff7b72{{ $Te6edf3tTff7b72(Ta5d6ff"relay_chat.hub_icon_reset_default"Tff7b72) Tff7b72}}
Tff7b72</button>
Tff7b72<button Te6edf3type=Ta5d6ff"button" Te6edf3:class=Ta5d6ff"btnSecondary" @Te6edf3click=Ta5d6ff"$emit('close')"Tff7b72>
Tff7b72{{ $Te6edf3tTff7b72(Ta5d6ff"common.cancel"Tff7b72) Tff7b72}}
Tff7b72</button>
Tff7b72</div>
Tff7b72</div>
Tff7b72</div>
Tff7b72</template>
Tff7b72<scriptTff7b72>
import { nextTick } from "vue";
import MaterialDesignIcon from "./MaterialDesignIcon.vue";
import { buildMdiIconNames } from "../js/mdiIconNames.js";
const BTN_SECONDARY =
"inline-flex items-center justify-center gap-1.5 rounded-lg border border-sem-border bg-sem-surface-muted px-3 py-2 text-sm font-medium text-sem-fg transition hover:bg-sem-surface-raised";
export default {
name: "MdiIconPickerModal",
components: { MaterialDesignIcon },
props: {
open: {
type: Boolean,
default: false,
},
selectedIcon: {
type: String,
default: null,
},
previewIconClass: {
type: String,
default: "text-sem-fg-secondary",
},
},
emits: ["close", "select"],
data() {
return {
search: "",
maxSearchResults: 200,
iconNames: [],
btnSecondary: BTN_SECONDARY,
};
},
computed: {
searchedIconNames() {
const q = this.search.trim().toLowerCase();
const list = q ? this.iconNames.filter((name) => name.includes(q)) : this.iconNames;
return list.slice(0, this.maxSearchResults);
},
},
watch: {
open(isOpen) {
if (isOpen) {
this.search = "";
nextTick(() => {
const el = this.$refs.searchInput;
if (el && typeof el.focus === "function") {
el.focus();
}
});
}
},
},
mounted() {
this.iconNames = buildMdiIconNames();
},
methods: {
pick(iconName) {
this.$emit("select", iconName);
this.$emit("close");
},
},
};
Tff7b72</script>
Served by rngit 1.5.2 - Generated in 0.04s